using CodePlex.DnD4eCampaignManager.DnD4e;
using CodePlex.DnD4eCampaignManager.DnD4e.Enums;
using CodePlex.DnD4eCampaignManager.Services;
using CodePlex.DnD4eCampaignManager.Services.Interfaces;
using NUnit.Framework;

namespace CodePlex.DnD4eCampaignManager.CampaignManagerTests.ServiceTests
{
    [TestFixture]
    public class DungeonsAndDragonsInsiderPlayerCharacterImporterTests
    {
        private const string VALID_PLAYER_CHARACTER_FILE_PATH = "TestUtilities\\CharacterBuilder.07a.dnd4e";
        private IDungeonsAndDragonsInsiderPlayerCharacterImporter _playerCharacterImporter;

        [Test]
        public void ChecksThatTheFileIsCorrect()
        {
            bool versionCanBeImported = _playerCharacterImporter.CanFileBeImported(VALID_PLAYER_CHARACTER_FILE_PATH);
            Assert.IsTrue(versionCanBeImported);
        }

        [Test]
        public void ImportPlayerCharacterCorrectlyReadsBasicCharacterInfoFromFile()
        {
            PlayerCharacter playerCharacter = _playerCharacterImporter.ImportPlayerCharacter(VALID_PLAYER_CHARACTER_FILE_PATH);
            Assert.AreEqual("Sha-Ashar", playerCharacter.Name);
            Assert.AreEqual("Sha-Ashar", playerCharacter.CharacterName);
            Assert.AreEqual(22, playerCharacter.CharacterAge);
            Assert.AreEqual(2250, playerCharacter.CharacterExperiencePoints);
            Assert.AreEqual(Alignment.Good, playerCharacter.CharacterAlignment);
            Assert.AreEqual("5'7\"", playerCharacter.CharacterHeight);
            Assert.AreEqual(195, playerCharacter.CharacterWeight);
            Assert.AreEqual("Fighter", playerCharacter.CharacterClass);
            Assert.AreEqual("Bahamut", playerCharacter.CharacterDeity);
            Assert.AreEqual("Earthshock Master, Toughness, Two-Weapon Defense", playerCharacter.CharacterFeats);
            Assert.AreEqual(Gender.Male, playerCharacter.CharacterGender);
            Assert.AreEqual(string.Empty, playerCharacter.CharacterParagonPath);
            Assert.AreEqual(string.Empty, playerCharacter.CharacterEpicDestiny);
            Assert.AreEqual("Genasi", playerCharacter.CharacterRace);
            Assert.AreEqual("Corpse Light, Endure Elements, Make Whole, Silence, Unseen Servant", playerCharacter.CharacterRituals);
        }

        [Test]
        public void ImportPlayerCharacterCorrectlyReadsCharacterAbilityScoresFromFile()
        {
            PlayerCharacter playerCharacter = _playerCharacterImporter.ImportPlayerCharacter(VALID_PLAYER_CHARACTER_FILE_PATH);
            Assert.AreEqual(17, playerCharacter.AbilityStrength);
            Assert.AreEqual(16, playerCharacter.AbilityConstitution);
            Assert.AreEqual(8, playerCharacter.AbilityDexterity);
            Assert.AreEqual(12, playerCharacter.AbilityIntelligence);
            Assert.AreEqual(13, playerCharacter.AbilityWisdom);
            Assert.AreEqual(10, playerCharacter.AbilityCharisma);
        }

        [Test]
        public void ImportPlayerCharacterCorrectlyReadsCharacterDefensesFromFile()
        {
            PlayerCharacter playerCharacter = _playerCharacterImporter.ImportPlayerCharacter(VALID_PLAYER_CHARACTER_FILE_PATH);
            Assert.AreEqual(19, playerCharacter.DefenseArmorClass);
            Assert.AreEqual(16, playerCharacter.DefenseFortitude);
            Assert.AreEqual(13, playerCharacter.DefenseReflex);
            Assert.AreEqual(12, playerCharacter.DefenseWillpower);
        }

        [Test]
        public void ImportPlayerCharacterCorrectlyReadsCharacterHealthFromFile()
        {
            PlayerCharacter playerCharacter = _playerCharacterImporter.ImportPlayerCharacter(VALID_PLAYER_CHARACTER_FILE_PATH);
            Assert.AreEqual(12, playerCharacter.HealingSurgeValue);
            Assert.AreEqual(12, playerCharacter.HealingSurgesMaximum);
            Assert.AreEqual(12, playerCharacter.HealingSurgesCurrent);
            Assert.AreEqual(49, playerCharacter.HitPointsMaximum);
            Assert.AreEqual(49, playerCharacter.HitPointsCurrent);
            Assert.AreEqual(0, playerCharacter.HitPointsTemporary);
        }

        [Test]
        public void ImportPlayerCharacterCorrectlyReadsCharacterInitiativeAndMovementFromFile()
        {
            PlayerCharacter playerCharacter = _playerCharacterImporter.ImportPlayerCharacter(VALID_PLAYER_CHARACTER_FILE_PATH);
            Assert.AreEqual(7, playerCharacter.InitiativeModifier);
            Assert.AreEqual(10, playerCharacter.InitiativeRoll);
            Assert.AreEqual(17, playerCharacter.InitiativeScore);
            Assert.AreEqual(5, playerCharacter.MovementSpeed);
            Assert.AreEqual(string.Empty, playerCharacter.MovementSpeedOther);
            Assert.AreEqual(-1, playerCharacter.MovementStealth);
        }

        [Test]
        public void ImportPlayerCharacterCorrectlyReadsCharacterPowersAndTacticsFromFile()
        {
            PlayerCharacter playerCharacter = _playerCharacterImporter.ImportPlayerCharacter(VALID_PLAYER_CHARACTER_FILE_PATH);
            Assert.AreEqual("Combat Challenge, Dual Strike, Footwork Lure, Pass Forward", playerCharacter.PowersAtWill);
            Assert.AreEqual("Crushing Blow, Earthshock, Funneling Flurry", playerCharacter.PowersEncounter);
            Assert.AreEqual("Tempest Dance", playerCharacter.PowersDaily);
            Assert.AreEqual(string.Empty, playerCharacter.Tactics);
        }

        [Test]
        public void ImportPlayerCharacterCorrectlyReadsCharacterSensesFromFile()
        {
            PlayerCharacter playerCharacter = _playerCharacterImporter.ImportPlayerCharacter(VALID_PLAYER_CHARACTER_FILE_PATH);
            Assert.AreEqual(2, playerCharacter.SensesPerception);
            Assert.AreEqual(12, playerCharacter.SensesPerceptionPassive);
            Assert.AreEqual(3, playerCharacter.SensesInsight);
            Assert.AreEqual(13, playerCharacter.SensesInsightPassive);
            Assert.AreEqual(string.Empty, playerCharacter.SensesOther);
        }

        [Test]
        public void ImportPlayerCharacterReturnsNewPlayerCharacterObjectForValidFile()
        {
            _playerCharacterImporter = new DungeonsAndDragonsInsiderPlayerCharacterImporter();
            PlayerCharacter playerCharacter = _playerCharacterImporter.ImportPlayerCharacter(VALID_PLAYER_CHARACTER_FILE_PATH);
            Assert.IsNotNull(playerCharacter);
            Assert.IsInstanceOfType(typeof ( PlayerCharacter ), playerCharacter);
        }

        [Test]
        public void ImportPlayerCharacterReturnsNullForInvalidFile()
        {
            _playerCharacterImporter = new DungeonsAndDragonsInsiderPlayerCharacterImporter();
            PlayerCharacter playerCharacter = _playerCharacterImporter.ImportPlayerCharacter("TestUtilities\\NoFile.dnd4e");
            Assert.IsNull(playerCharacter);
        }

        [SetUp]
        public void SetUp()
        {
            _playerCharacterImporter = new DungeonsAndDragonsInsiderPlayerCharacterImporter();
        }
    }
}